package com.br.pathfinding.android;

import java.util.ArrayList;

public class Elemento {

	private ArrayList<Integer> valores;

	public ArrayList<Integer> getValores() {
		return valores;
	}

	public void setValores(ArrayList<Integer> valores) {
		this.valores = valores;
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Elemento> expandir(Nodo nodo) {

		ArrayList<Elemento> elementos = null;
		ArrayList<Integer> valores = null;
		Elemento elemento = null;

		elementos = new ArrayList<Elemento>();
		elemento = new Elemento();

		switch (nodo.getElemento().getValores().indexOf(0)) {
		case 0:
			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 0, 1));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 0, 3));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 1:
			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 1, 0));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 1, 2));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 1, 4));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 2:

			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 2, 1));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 2, 5));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 3:

			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 3, 0));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 3, 4));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 3, 6));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 4:

			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 4, 1));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 4, 3));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 4, 5));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 4, 7));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 5:

			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 5, 2));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 5, 4));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 5, 8));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 6:
			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 6, 3));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 6, 7));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 7:
			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 7, 4));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 7, 6));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 7, 8));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		case 8:
			valores = (ArrayList<Integer>) nodo.getElemento().getValores()
					.clone();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 8, 5));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			elemento = new Elemento();

			elemento.setValores(Elemento.mudaValores(
					(ArrayList<Integer>) valores.clone(), 8, 7));

			if (!testaExistencia(elemento.getValores())) {
				IABreadthFirst.possibilidades.add(elemento.getValores());
				elementos.add(elemento);
			}

			break;
		default:

			break;
		}

		return elementos;

	}

	public static boolean testaExistencia(ArrayList<Integer> possibilidade) {

		return IABreadthFirst.possibilidades.indexOf(possibilidade) != -1 ? true
				: false;

	}

	private static ArrayList<Integer> mudaValores(ArrayList<Integer> valores,
			Integer posicaoZero, Integer posicaoMudar) {

		@SuppressWarnings("unchecked")
		ArrayList<Integer> valoresNovos = (ArrayList<Integer>) valores.clone();

		int valor;

		valor = valoresNovos.get(posicaoMudar);

		valoresNovos.set(posicaoZero, valor);
		valoresNovos.set(posicaoMudar, 0);

		return valoresNovos;

	}
}
